【PHP】アクセス修飾子 - クラスのプロパティにおけるアクセス制御
クラスにはアクセス修飾子と呼ぶ仕組みがあります。
アクセス修飾子を使うことで、クラスのフィールドやメソッドへのアクセスを制御することができます。/p>
ここでは、アクセス修飾子について解説します。
検証環境
アクセス修飾子
アクセス修飾子は“クラスへのアクセスを制御する仕組み”です。
クラス外部・クラス内部・サブクラスからのアクセスについて、フィールドやメソッドなどに個別にアクセス権を付与して制御することができます。
種類
アクセス修飾子の種類はpublic
、protected
、private
の3つです。
各アクセス修飾子とアクセス元の制限は次のようになります。
アクセス元 | public | protected | private |
---|---|---|---|
クラス内部 | ○ | ○ | ○ |
サブクラス | ○ | ○ | × |
クラス外部 | ○ | × | × |
基本構文
class クラス名 {
// クラス定数
アクセス修飾子 クラス定数名;
// クラス変数
アクセス修飾子 static クラス変数;
// クラスメソッド
アクセス修飾子 static function メソッド名() {}
// フィールド
アクセス修飾子 フィールド名;
// メソッド
アクセス修飾子 function メソッド名() {}
}
アクセス修飾子はプロパティ(クラス定数やクラス変数、フィールド、メソッドなど)の定義の先頭に記述します。
アクセス修飾子の記述がないプロパティは、自動でpublic
になりますが、アクセス権を明確にするため、極力明記することを推奨します。
アクセス制御の確認
次のAccessTest
クラスを使って、アクセス制御を確認します。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
}
?>
AccessTest
クラスはクラス定数・クラス変数・クラスメソッド・フィールド・メソッドに対して3つのアクセス修飾子(public
/protected
/private
)を所持します。
クラス内部からのアクセス
クラス内部からアクセスするため、executeメソッドを定義し、呼び出します。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
___ih_diff_start
+ /**************************************************************
+ * クラス内部からのアクセス
+ ***************************************************************/
+ function execute() {
+
+ /*
+ * クラス定数
+ *****************************************************/
+ echo self::CONST_PUBLIC;
+ echo self::CONST_PROTECTED;
+ echo self::CONST_PRIVATE;
+
+ /*
+ * クラス変数
+ *****************************************************/
+ echo self::$class_variable_public;
+ echo self::$class_variable_protected;
+ echo self::$class_variable_private;
+
+ /*
+ * クラスメソッド
+ *****************************************************/
+ self::class_method_public();
+ self::class_method_protected();
+ self::class_method_private();
+
+ /*
+ * フィールド
+ *****************************************************/
+ echo $this->field_public;
+ echo $this->field_protected;
+ echo $this->field_private;
+
+ /*
+ * メソッド
+ *****************************************************/
+ $this->method_public();
+ $this->method_protected();
+ $this->method_private();
+
+ }
___ih_diff_end
}
___ih_diff_start
+$access_test = new AccessTest();
+$access_test->execute();
___ih_diff_end
?>
$ php sample1.php
CONST_PUBLIC : SUCCESS!
CONST_PROTECTED : SUCCESS!
CONST_PRIVATE : SUCCESS!
class_variable_public : SUCCESS!
class_variable_protected : SUCCESS!
class_variable_private : SUCCESS!
class_method_public : SUCCESS!
class_method_protected : SUCCESS!
class_method_private : SUCCESS!
field_public : SUCCESS!
field_protected : SUCCESS!
field_private : SUCCESS!
method_public : SUCCESS!
method_protected : SUCCESS!
method_private : SUCCESS!
実行結果から全てのプロパティにアクセスできたことが分かります。
サブクラスからのアクセス
AccessTest
クラスを継承したSubAccessTest
クラスを定義します。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
}
___ih_diff_start
+class SubAccessTest extends AccessTest {
+
+ /**************************************************************
+ * サブクラス
+ ***************************************************************/
+ public function execute() {
+
+ /*
+ * クラス定数
+ *****************************************************/
+ echo self::CONST_PUBLIC;
+ echo self::CONST_PROTECTED;
+ echo self::CONST_PRIVATE;
+
+ /*
+ * クラス変数
+ *****************************************************/
+ echo self::$class_variable_public;
+ echo self::$class_variable_protected;
+ echo self::$class_variable_private;
+
+ /*
+ * クラスメソッド
+ *****************************************************/
+ self::class_method_public();
+ self::class_method_protected();
+ self::class_method_private();
+
+ /*
+ * フィールド
+ *****************************************************/
+ echo $this->field_public;
+ echo $this->field_protected;
+ echo $this->field_private;
+
+ /*
+ * メソッド
+ *****************************************************/
+ $this->method_public();
+ $this->method_protected();
+ $this->method_private();
+
+ }
+
+}
___ih_diff_end
___ih_diff_start
+$access_test = new SubAccessTest();
+$access_test->execute();
___ih_diff_end
?>
$ php sample2.php
CONST_PUBLIC : SUCCESS!
CONST_PROTECTED : SUCCESS!
PHP Fatal error: Uncaught Error: Undefined constant SubAccessTest::CONST_PRIVATE in sample2.php:97
Stack trace:
#0 sample.php(132): SubAccessTest->execute()
#1 {main}
thrown in sample2.php on line 97
AccessTest
クラスのプロパティにサブクラスであるSubAccessTest
のexecute
メソッドからアクセスするとエラーが発生します。
この原因はprivate
なプロパティにアクセスしているためです。
private
なプロパティへのアクセスを削除し、改めて実行します。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
}
class SubAccessTest extends AccessTest {
/**************************************************************
* サブクラス
***************************************************************/
public function execute() {
/*
* クラス定数
*****************************************************/
echo self::CONST_PUBLIC;
echo self::CONST_PROTECTED;
___ih_diff_start
- echo self::CONST_PRIVATE;
___ih_diff_end
/*
* クラス変数
*****************************************************/
echo self::$class_variable_public;
echo self::$class_variable_protected;
___ih_diff_start
- echo self::$class_variable_private;
___ih_diff_end
/*
* クラスメソッド
*****************************************************/
self::class_method_public();
self::class_method_protected();
___ih_diff_start
- self::class_method_private();
___ih_diff_end
/*
* フィールド
*****************************************************/
echo $this->field_public;
echo $this->field_protected;
___ih_diff_start
- echo $this->field_private;
___ih_diff_end
/*
* メソッド
*****************************************************/
$this->method_public();
$this->method_protected();
___ih_diff_start
- $this->method_private();
___ih_diff_end
}
}
___ih_diff_end
___ih_diff_start
+$access_test = new SubAccessTest();
+$access_test->execute();
___ih_diff_end
?>
$ php sample2.php
CONST_PUBLIC : SUCCESS!
CONST_PROTECTED : SUCCESS!
class_variable_public : SUCCESS!
class_variable_protected : SUCCESS!
class_method_public : SUCCESS!
class_method_protected : SUCCESS!
field_public : SUCCESS!
field_protected : SUCCESS!
method_public : SUCCESS!
method_protected : SUCCESS!
正常に実行されました。
この結果からサブクラスではpublicとprotectedにアクセスできることが分かります。
クラス外部からのアクセス
AccessTestクラスについて外部(クラス自身でもサブクラスでもないところ)からアクセスしてみましょう。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
}
___ih_diff_start
+/**************************************************************
+* クラス外部
+***************************************************************/
+$access_test = new AccessTest();
+
+/*
+* クラス定数
+*****************************************************/
+echo AccessTest::CONST_PUBLIC;
+echo AccessTest::CONST_PROTECTED;
+echo AccessTest::CONST_PRIVATE;
+
+/*
+* クラス変数
+*****************************************************/
+echo AccessTest::$class_variable_public;
+echo AccessTest::$class_variable_protected;
+echo AccessTest::$class_variable_private;
+
+/*
+* クラスメソッド
+*****************************************************/
+AccessTest::class_method_public();
+AccessTest::class_method_protected();
+AccessTest::class_method_private();
+
+/*
+* フィールド
+*****************************************************/
+echo $access_test->field_public;
+echo $access_test->field_protected;
+echo $access_test->field_private;
+
+/*
+* メソッド
+*****************************************************/
+$access_test->method_public();
+$access_test->method_protected();
+$access_test->method_private();
___ih_diff_end
?>
$ php sample3.php
CONST_PUBLIC : SUCCESS!
PHP Fatal error: Uncaught Error: Cannot access protected constant AccessTest::CONST_PROTECTED in sample3.php:52
Stack trace:
#0 {main}
thrown in sample3.php on line 52
クラス外部からアクセスするとエラーが発生します。
この原因はprotected
なプロパティにアクセスしているためで、private
なプロパティにアクセスした場合も同様のエラーが発生します。
protected
とprivate
なプロパティへのアクセスを削除し、改めて実行します。
<?php
// クラス
class AccessTest {
/*
* クラス定数
*****************************************************/
public const CONST_PUBLIC = "CONST_PUBLIC : SUCCESS!\n";
protected const CONST_PROTECTED = "CONST_PROTECTED : SUCCESS!\n";
private const CONST_PRIVATE = "CONST_PRIVATE : SUCCESS!\n";
/*
* クラス変数
*****************************************************/
public static $class_variable_public = "class_variable_public : SUCCESS!\n";
protected static $class_variable_protected = "class_variable_protected : SUCCESS!\n";
private static $class_variable_private = "class_variable_private : SUCCESS!\n";
/*
* クラスメソッド
*****************************************************/
public static function class_method_public() { echo "class_method_public : SUCCESS!\n"; }
protected static function class_method_protected() { echo "class_method_protected : SUCCESS!\n"; }
private static function class_method_private() { echo "class_method_private : SUCCESS!\n"; }
/*
* フィールド
*****************************************************/
public $field_public = "field_public : SUCCESS!\n";
protected $field_protected = "field_protected : SUCCESS!\n";
private $field_private = "field_private : SUCCESS!\n";
/*
* メソッド
*****************************************************/
public function method_public() { echo "method_public : SUCCESS!\n"; }
protected function method_protected() { echo "method_protected : SUCCESS!\n"; }
private function method_private() { echo "method_private : SUCCESS!\n"; }
}
/**************************************************************
* クラス外部
***************************************************************/
$access_test = new AccessTest();
/*
* クラス定数
*****************************************************/
echo AccessTest::CONST_PUBLIC;
___ih_diff_start
-echo AccessTest::CONST_PROTECTED;
-echo AccessTest::CONST_PRIVATE;
___ih_diff_end
/*
* クラス変数
*****************************************************/
echo AccessTest::$class_variable_public;
___ih_diff_start
-echo AccessTest::$class_variable_protected;
-echo AccessTest::$class_variable_private;
___ih_diff_end
/*
* クラスメソッド
*****************************************************/
AccessTest::class_method_public();
___ih_diff_start
-AccessTest::class_method_protected();
-AccessTest::class_method_private();
___ih_diff_end
/*
* フィールド
*****************************************************/
echo $access_test->field_public;
___ih_diff_start
-echo $access_test->field_protected;
-echo $access_test->field_private;
___ih_diff_end
/*
* メソッド
*****************************************************/
$access_test->method_public();
___ih_diff_start
-$access_test->method_protected();
-$access_test->method_private();
___ih_diff_end
?>
$ php sample3.php
CONST_PUBLIC : SUCCESS!
class_variable_public : SUCCESS!
class_method_public : SUCCESS!
field_public : SUCCESS!
method_public : SUCCESS!
正常に実行されました。
この結果からクラス外部からはpublic
なプロパティのみアクセスできることが分かります。